#include "Music_gui.h"
#include "lvgl/lvgl.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>

#define BOTTOM_CONT_HEIGHT 80
#define MUSIC_LIST_WIDTH 330

LV_IMG_DECLARE(butterfly)
LV_IMG_DECLARE(mode_all_circle)
LV_IMG_DECLARE(next)
LV_IMG_DECLARE(prev)
LV_IMG_DECLARE(mode_one_circle)
LV_IMG_DECLARE(pause)
LV_IMG_DECLARE(playing)
LV_IMG_DECLARE(mode_random)
LV_IMG_DECLARE(volume)

LV_FONT_DECLARE(lv_font_mh_14)
LV_FONT_DECLARE(lv_font_mh_16)
LV_FONT_DECLARE(lv_font_mh_18)
LV_FONT_DECLARE(lv_font_mh_22)


typedef struct
{
  lv_obj_t *cont;        // 容器
  lv_obj_t *prog_slider; // 音乐进度滑动条
  lv_obj_t *prev;        // 上一曲
  lv_obj_t *pause;       // 暂停
  lv_obj_t *next;        // 下一曲
  lv_obj_t *mode;        // 模式-单曲，随机，顺序
  lv_obj_t *volume;      // 用于弹出音量调节slider
  lv_obj_t *time_label;  // 播放时间label
  lv_obj_t *music_label; // 歌曲名称label
} MusicBottomObj;

static void drag_event_handler(lv_event_t *e);
static void music_bottom_prev_btn_click_event_cb(lv_event_t *e);
static void music_bottom_next_btn_click_event_cb(lv_event_t *e);
static void music_bottom_pause_btn_click_event_cb(lv_event_t *e);
static void music_bottom_mode_btn_click_event_cb(lv_event_t *e);
static void music_bottom_volume_btn_click_event_cb(lv_event_t *e);
static void music_list_btn_event_cb(lv_event_t *e);
static void music_progress_slider_event_cb(lv_event_t *e);
static void music_volume_slider_event_cb(lv_event_t *e);

// LCD分辨率
static lv_coord_t lcd_w = 480;
static lv_coord_t lcd_h = 272;

// 界面回调函数集合
static gui_opt_t gui_opts;

// 背景图片
static lv_obj_t *back_img;

// 退出按钮
static lv_obj_t *exit_btn;

// 音乐列表
static lv_obj_t *music_list;

// 底部元素集合
static MusicBottomObj music_bobj;

// 歌词滚轮
static lv_obj_t *lyric_roller;

// 保存当前播放的音乐列表btn
static lv_obj_t *playing_music_btn = NULL;

//音量调节slider
static lv_obj_t *volume_slider = NULL;

//音乐进度slider是否被按下
static bool music_slider_pressed = false;

/*
  *@brief 初始化界面UI
  ×@param opts UI回调函数集合
  */
void music_gui_init(gui_opt_t *opts)
{
  if (opts != NULL)
    memcpy(&gui_opts, opts, sizeof(gui_opt_t));

  lcd_w = lv_disp_get_hor_res(NULL);
  lcd_h = lv_disp_get_ver_res(NULL);

  back_img = lv_img_create(lv_scr_act());
  lv_obj_set_size(back_img, lcd_w, lcd_h);
  lv_obj_center(back_img);
  lv_obj_clear_flag(back_img, LV_OBJ_FLAG_SCROLLABLE); // 禁止滚动
  lv_img_set_src(back_img, "S:./res/background/musicbg.bin");

  // 创建底部元素
  music_bobj.cont = lv_obj_create(back_img);
  lv_obj_set_size(music_bobj.cont, lcd_w, BOTTOM_CONT_HEIGHT);
  lv_obj_align(music_bobj.cont, LV_ALIGN_BOTTOM_MID, 0, 0);
  lv_obj_clear_flag(music_bobj.cont, LV_OBJ_FLAG_SCROLLABLE); // 禁止滚动
  lv_obj_set_style_radius(music_bobj.cont, 0, LV_STATE_DEFAULT);
  lv_obj_set_style_border_width(music_bobj.cont, 0, LV_STATE_DEFAULT);                  // 无边框
  lv_obj_set_style_bg_color(music_bobj.cont, lv_color_hex(0x000000), LV_STATE_DEFAULT); // 背景黑色
  lv_obj_set_style_bg_opa(music_bobj.cont, LV_OPA_50, LV_STATE_DEFAULT);                // 背景透明度

  do
  {
    const lv_img_dsc_t *icon[] = {&prev, &pause, &next, &mode_all_circle, &volume};
    lv_obj_t **imgs[] = {&music_bobj.prev, &music_bobj.pause, &music_bobj.next, &music_bobj.mode, &music_bobj.volume};
    lv_event_cb_t img_cbs[] =
        {
            music_bottom_prev_btn_click_event_cb,
            music_bottom_pause_btn_click_event_cb,
            music_bottom_next_btn_click_event_cb,
            music_bottom_mode_btn_click_event_cb,
            music_bottom_volume_btn_click_event_cb};

    for (int i = 0; i < 5; i++) // 创建5img按钮
    {
      imgs[i][0] = lv_img_create(music_bobj.cont); // img按钮
      lv_img_set_src(imgs[i][0], icon[i]);
      lv_obj_set_style_img_opa(imgs[i][0], LV_OPA_60, LV_STATE_DEFAULT);    // 松开时透明度
      lv_obj_set_style_img_opa(imgs[i][0], LV_OPA_COVER, LV_STATE_PRESSED); // 按下时透明度
      lv_obj_add_flag(imgs[i][0], LV_OBJ_FLAG_CLICKABLE);
      lv_obj_add_event_cb(imgs[i][0], img_cbs[i], LV_EVENT_SHORT_CLICKED, NULL);

      if (i != 0)
        lv_obj_align_to(imgs[i][0], imgs[i - 1][0], LV_ALIGN_OUT_RIGHT_MID, 10, 0);
      else
        lv_obj_align(imgs[i][0], LV_ALIGN_LEFT_MID, 0, 0);
    }
  } while (0);

  // 创建音乐进度滑块条
  music_bobj.prog_slider = lv_slider_create(music_bobj.cont);
  lv_obj_set_size(music_bobj.prog_slider, 500, 10);
  lv_obj_set_style_bg_color(music_bobj.prog_slider, lv_color_hex(0xe6e6e6), LV_STATE_DEFAULT);
  lv_obj_set_style_bg_opa(music_bobj.prog_slider, LV_OPA_60, LV_STATE_DEFAULT);
  lv_obj_set_style_bg_color(music_bobj.prog_slider, lv_color_hex(0x60bf25), LV_PART_INDICATOR | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_color(music_bobj.prog_slider, lv_color_hex(0x60bf25), LV_PART_KNOB | LV_STATE_DEFAULT);
  lv_obj_align_to(music_bobj.prog_slider, music_bobj.next, LV_ALIGN_OUT_RIGHT_MID, 15, 0);
  lv_obj_add_event_cb(music_bobj.prog_slider, music_progress_slider_event_cb, LV_EVENT_RELEASED, NULL);
  lv_obj_add_event_cb(music_bobj.prog_slider, music_progress_slider_event_cb, LV_EVENT_PRESSED, NULL);

  lv_obj_t *music_name_label = lv_label_create(music_bobj.cont);
  lv_obj_set_style_text_font(music_name_label, &lv_font_mh_16, LV_STATE_DEFAULT);
  lv_obj_set_style_text_color(music_name_label, lv_color_hex(0xe6e6e6), LV_STATE_DEFAULT);
  lv_label_set_text(music_name_label, "当前无歌曲播放");
  lv_obj_align_to(music_name_label, music_bobj.prog_slider, LV_ALIGN_OUT_TOP_LEFT, 0, -5);
  music_bobj.music_label = music_name_label;

  lv_obj_t *time_label = lv_label_create(music_bobj.cont);
  lv_obj_set_style_text_font(time_label, &lv_font_mh_14, LV_STATE_DEFAULT);
  lv_obj_set_style_text_color(time_label, lv_color_hex(0xe6e6e6), LV_STATE_DEFAULT);
  lv_label_set_text(time_label, "00:00/00:00");
  lv_obj_set_user_data(music_bobj.prog_slider, time_label);
  lv_obj_align_to(time_label, music_bobj.prog_slider, LV_ALIGN_OUT_RIGHT_MID, 15, 0);
  music_bobj.time_label = time_label;

  lv_obj_align_to(music_bobj.mode, time_label, LV_ALIGN_OUT_RIGHT_MID, 10, 0);
  lv_obj_align_to(music_bobj.volume, music_bobj.mode, LV_ALIGN_OUT_RIGHT_MID, 10, 0);

  // 创建音乐列表
  music_list = lv_list_create(back_img);
  lv_obj_set_size(music_list, MUSIC_LIST_WIDTH, lcd_h - BOTTOM_CONT_HEIGHT);
  lv_obj_align(music_list, LV_ALIGN_TOP_LEFT, 0, 0);
  lv_obj_set_style_bg_opa(music_list, LV_OPA_30, LV_STATE_DEFAULT);          // 设置背景透明度
  lv_obj_set_style_bg_color(music_list, lv_color_black(), LV_STATE_DEFAULT); // 背景黑色
  lv_obj_set_style_border_opa(music_list, LV_OPA_TRANSP, LV_STATE_DEFAULT);  // 设置边框透明
  lv_obj_set_style_radius(music_list, 0, LV_STATE_DEFAULT);                  // 边框圆角为0

  //创建歌词滚筒
  lyric_roller = lv_roller_create(back_img);
  lv_obj_set_size(lyric_roller, lcd_w - MUSIC_LIST_WIDTH, 250 );
  lv_obj_align(lyric_roller, LV_ALIGN_RIGHT_MID, 0, 0);     //设置对齐
  lv_obj_clear_flag(lyric_roller, LV_OBJ_FLAG_SCROLLABLE | LV_OBJ_FLAG_CLICKABLE);      //不可滚动不可点击
  lv_obj_set_style_bg_opa(lyric_roller, LV_OPA_TRANSP, LV_STATE_DEFAULT);   //背景透明
  lv_obj_set_style_border_opa(lyric_roller, LV_OPA_TRANSP, LV_STATE_DEFAULT);   //边框透明
  lv_obj_set_style_bg_opa(lyric_roller, LV_OPA_TRANSP, LV_PART_SELECTED | LV_STATE_DEFAULT);   //选中项背景透明
  lv_obj_set_style_text_font(lyric_roller, &lv_font_mh_18, LV_STATE_DEFAULT);     //非选中项字体
  lv_obj_set_style_text_font(lyric_roller, &lv_font_mh_22, LV_PART_SELECTED | LV_STATE_DEFAULT);     //选中项字体
  lv_obj_set_style_text_color(lyric_roller, lv_color_hex(0xffffff), LV_STATE_DEFAULT);
  lv_obj_set_style_text_color(lyric_roller, lv_color_hex(0xe9de9e), LV_PART_SELECTED | LV_STATE_DEFAULT);   //字体颜色
  lv_roller_set_options(lyric_roller, "开启音乐之旅吧~", LV_ROLLER_MODE_NORMAL);
  lv_roller_set_visible_row_count(lyric_roller, 5);     //可见行数5行

  //创建音量slider
  volume_slider = lv_slider_create(back_img);
  lv_obj_set_size(volume_slider, 10, 150);

  lv_coord_t x = lcd_w - 40;
  lv_coord_t y = lcd_h - BOTTOM_CONT_HEIGHT - 150 - 10;
  lv_obj_set_pos(volume_slider, x, y);

  int cur = 50;
  int max = 100;
  if(gui_opts.music_get_volume != NULL)     //获取当前音量和最大值
    gui_opts.music_get_volume(&cur, &max);

  lv_slider_set_range(volume_slider, 0, max);
  lv_slider_set_value(volume_slider, cur, LV_ANIM_OFF);
  lv_obj_add_event_cb(volume_slider, music_volume_slider_event_cb, LV_EVENT_RELEASED, NULL);
  lv_obj_set_style_bg_color(volume_slider, lv_color_hex(0xe6e6e6), LV_STATE_DEFAULT);
  lv_obj_set_style_bg_opa(volume_slider, LV_OPA_60, LV_STATE_DEFAULT);
  lv_obj_set_style_bg_color(volume_slider, lv_color_hex(0x60bf25), LV_PART_INDICATOR | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_color(volume_slider, lv_color_hex(0x60bf25), LV_PART_KNOB | LV_STATE_DEFAULT);
  lv_obj_add_flag(volume_slider, LV_OBJ_FLAG_HIDDEN);     //隐藏对象

  // 创建退出按钮
  exit_btn = lv_obj_create(back_img);
  lv_obj_set_size(exit_btn, 70, 70);
  lv_obj_set_pos(exit_btn, 935, 200);
  lv_obj_clear_flag(exit_btn, LV_OBJ_FLAG_SCROLLABLE); // 禁止滚动
  lv_obj_set_style_radius(exit_btn, 35, LV_STATE_DEFAULT);
  lv_obj_set_style_bg_color(exit_btn, lv_color_hex(0xffffff), LV_STATE_DEFAULT);
  lv_obj_set_style_border_opa(exit_btn, LV_OPA_TRANSP, LV_STATE_DEFAULT); // A边框透明
  lv_obj_set_style_bg_opa(exit_btn, LV_OPA_50, LV_STATE_DEFAULT);
  lv_obj_set_style_bg_opa(exit_btn, LV_OPA_90, LV_STATE_PRESSED);

  lv_obj_t *img = lv_img_create(exit_btn);
  lv_img_set_src(img, &butterfly);
  lv_obj_align(img, LV_ALIGN_CENTER, 0, 0);
  lv_obj_add_flag(img, LV_OBJ_FLAG_EVENT_BUBBLE);

  lv_obj_add_event_cb(exit_btn, drag_event_handler, LV_EVENT_PRESSING, NULL);
  if (gui_opts.exit_cb != NULL)
    lv_obj_add_event_cb(exit_btn, gui_opts.exit_cb, LV_EVENT_SHORT_CLICKED, NULL);
}

/*
 *@brief 释放界面UI
 */
void music_gui_release(void)
{
  lv_obj_t *btn = NULL;

  while ((btn = lv_obj_get_child(music_list, -1)) != NULL)
  {
    void *music_name = lv_obj_get_user_data(btn);
    if (music_name != NULL)
      free(music_name);

    lv_obj_del(btn);
  }

  lv_obj_del(back_img);
}

/*
 *@brief 添加一个音乐到列表
 *@param name 音乐文件名称
 */
void music_gui_add_music_list(const char *name)
{
  // 添加一个按钮到list
  lv_obj_t *btn = lv_list_add_btn(music_list, NULL, name);
  lv_obj_set_style_bg_opa(btn, LV_OPA_TRANSP, LV_STATE_DEFAULT); // 设置背景透明
  lv_obj_set_style_bg_opa(btn, LV_OPA_30, LV_STATE_PRESSED);     // 设置背景透明度(按下时)
  lv_obj_set_style_text_color(btn, lv_color_hex(0xffffff), LV_STATE_DEFAULT);
  lv_obj_set_style_text_font(btn, &lv_font_mh_18, LV_STATE_DEFAULT); // 设置字体
  lv_obj_add_event_cb(btn, music_list_btn_event_cb, LV_EVENT_SHORT_CLICKED, NULL);
  lv_obj_t *label = lv_obj_get_child(btn, -1);
  if(label != NULL)
    lv_label_set_long_mode(label, LV_LABEL_LONG_DOT);

  if (playing_music_btn == NULL)
    playing_music_btn = btn; // 保存地一首歌

  int len = strlen(name) + 1;
  char *music_name = malloc(len);
  strcpy(music_name, name);

  lv_obj_set_user_data(btn, music_name);
}

/*
 *@brief 设置音乐播放进度显示
 */
void music_gui_set_progress(int cur, int total)
{
  lv_slider_set_range(music_bobj.prog_slider, 0, total);
  if(music_slider_pressed != true)       //未按下时设置
    lv_slider_set_value(music_bobj.prog_slider, cur, LV_ANIM_OFF);

  lv_label_set_text_fmt(music_bobj.time_label, "%d:%d/%d:%d", cur / 60, cur % 60, total / 60, total % 60);
}

/*
 *@brief 加载歌词到UI
 *@param lyric 使用\n隔开的所有歌词
 */
void music_gui_load_lyric(const char *lyric)
{
  if(lyric != NULL)
    lv_roller_set_options(lyric_roller, lyric, LV_ROLLER_MODE_NORMAL);
  else
    lv_roller_set_options(lyric_roller, "没有找到歌词文件", LV_ROLLER_MODE_NORMAL);
}

/*
 *@brief 设置当前歌词
 *@param id 歌词id
 */
void music_gui_set_lyric_id(int id)
{
  if(id < 0)
    return;

  lv_anim_enable_t anim = id > 0 ? LV_ANIM_ON : LV_ANIM_OFF;
  lv_roller_set_selected(lyric_roller, id, anim);
}

/*
 *@brief 根据索引获取对应的音乐文件名
 *@param index 索引
 */
const char *music_gui_get_music_name(int index)
{
  const char *name = NULL;

  lv_obj_t *btn = lv_obj_get_child(music_list, index);
  if(btn != NULL)
  {
    playing_music_btn = btn;
    name = lv_obj_get_user_data(btn);
  }

  return name;
}

/*
 *@brief 在底部显示音乐名称
 *@param name 音乐名
 */
void music_gui_show_music_name(const char *name)
{
  if(name != NULL)
    lv_label_set_text(music_bobj.music_label, name);
}

/*
 *@brief 长按拖动控件事件函数
 */
static void drag_event_handler(lv_event_t *e)
{
  lv_obj_t *obj = lv_event_get_target(e);

  lv_indev_t *indev = lv_indev_get_act();
  if (indev == NULL)
    return;

  lv_point_t vect;
  lv_indev_get_vect(indev, &vect);

  lv_coord_t x = lv_obj_get_x(obj) + vect.x;
  lv_coord_t y = lv_obj_get_y(obj) + vect.y;
  lv_obj_set_pos(obj, x, y);
}

/*
 *@brief 底部上一曲按钮控件事件函数
 */
static void music_bottom_prev_btn_click_event_cb(lv_event_t *e)
{
  lv_obj_t *btn = lv_event_get_target(e);

  if (playing_music_btn != NULL)
  {
    int index = lv_obj_get_index(playing_music_btn); // 获取当前music btn索引
    index--;                                         // index若为-1,则表示最后一个btn，不需要对负数处理

    lv_obj_t *prev_btn = lv_obj_get_child(music_list, index); // 获取上一个music list btn
    if (prev_btn != NULL)
    {
      playing_music_btn = prev_btn;
      const char *music_name = lv_obj_get_user_data(prev_btn);
      if (gui_opts.music_play != NULL && music_name != NULL)
        gui_opts.music_play(music_name, index);

      lv_img_set_src(music_bobj.pause, &playing);
    }
  }
}

/*
 *@brief 底部下一曲按钮控件事件函数
 */
static void music_bottom_next_btn_click_event_cb(lv_event_t *e)
{
  lv_obj_t *btn = lv_event_get_target(e);

  if (playing_music_btn != NULL)
  {
    int index = lv_obj_get_index(playing_music_btn); // 获取当前music btn索引
    int total = lv_obj_get_child_cnt(music_list) - 1;
    index = index < total ? index + 1 : 0; // 设置下一个btn索引

    lv_obj_t *next_btn = lv_obj_get_child(music_list, index); // 获取下一个music list btn
    if (next_btn != NULL)
    {
      playing_music_btn = next_btn;
      const char *music_name = lv_obj_get_user_data(next_btn);
      if (gui_opts.music_play != NULL && music_name != NULL)
        gui_opts.music_play(music_name, index);

      lv_img_set_src(music_bobj.pause, &playing);
    }
  }
}

/*
 *@brief 底部暂停按钮控件事件函数
 */
static void music_bottom_pause_btn_click_event_cb(lv_event_t *e)
{
  lv_obj_t *btn = lv_event_get_target(e);

  int music_state = false;

  if (gui_opts.music_get_state != NULL)
    music_state = gui_opts.music_get_state();

  if (music_state < 0) // 还没有歌曲播放
  {
    if (playing_music_btn != NULL)
    {
      const char *music_name = lv_obj_get_user_data(playing_music_btn);
      if (gui_opts.music_play != NULL && music_name != NULL)
      {
        gui_opts.music_play(music_name, 0);
      }
    }
  }
  else
  {
    music_state = !music_state;

    if (music_state == true)
    {
      int index = lv_obj_get_index(playing_music_btn);

      if (gui_opts.music_play != NULL)
        gui_opts.music_play(NULL, index);
    }
    else
    {
      if (gui_opts.music_pause != NULL)
        gui_opts.music_pause();
    }
  }

  lv_img_set_src(music_bobj.pause, music_state ? &playing : &pause);
}

/*
 *@brief 底部模式按钮控件事件函数
 */
static void music_bottom_mode_btn_click_event_cb(lv_event_t *e)
{
  lv_obj_t *btn = lv_event_get_target(e);
  const lv_img_dsc_t *mode_src[] = {&mode_all_circle, &mode_one_circle, &mode_random};

  MusicMode m = MusicMode_ListLoop;

  if(gui_opts.music_get_mode != NULL)
    m = gui_opts.music_get_mode();

  m = m < MusicMode_Random ? m + 1 : MusicMode_ListLoop;

  if(gui_opts.music_set_mode != NULL)
    gui_opts.music_set_mode(m);

  lv_img_set_src(btn, mode_src[m]);
}

/*
 *@brief 底部音量按钮控件事件函数
 */
static void music_bottom_volume_btn_click_event_cb(lv_event_t *e)
{
  lv_obj_t *btn = lv_event_get_target(e);

  lv_obj_flag_t flag = volume_slider->flags & LV_OBJ_FLAG_HIDDEN;

  if(flag != 0)
    lv_obj_clear_flag(volume_slider, LV_OBJ_FLAG_HIDDEN);
  else
    lv_obj_add_flag(volume_slider, LV_OBJ_FLAG_HIDDEN);
}

/*
 *@brief 音乐列表按钮点击事件回调函数
 */
static void music_list_btn_event_cb(lv_event_t *e)
{
  lv_obj_t *btn = lv_event_get_target(e);

  const char *music_name = lv_obj_get_user_data(btn);

  playing_music_btn = btn;
  int index = lv_obj_get_index(playing_music_btn);

  if (gui_opts.music_play != NULL)
    gui_opts.music_play(music_name, index);

  lv_img_set_src(music_bobj.pause, &playing);
}

/*
 *@brief 音乐进度滑块条滑动事件函数
 */
static void music_progress_slider_event_cb(lv_event_t *e)
{
  lv_obj_t *slider = lv_event_get_target(e);
  lv_event_code_t e_code = lv_event_get_code(e);

  if(e_code == LV_EVENT_RELEASED)
  {
    music_slider_pressed = false;
    int cur = lv_slider_get_value(slider);

    if (gui_opts.music_set_cur != NULL)
      gui_opts.music_set_cur(cur);
  }
  else if(e_code == LV_EVENT_PRESSED)
  {
    music_slider_pressed = true;
  }
}

/*
 *@brief 音乐音量滑块条滑动事件函数
 */
static void music_volume_slider_event_cb(lv_event_t *e)
{
  lv_obj_t *slider = lv_event_get_target(e);
  int value = lv_slider_get_value(slider);

  if(gui_opts.music_set_volume != NULL)
    gui_opts.music_set_volume(value);     //设置音量
}